//---------------------------------------------------------
//	hash list definition
//---------------------------------------------------------
#ifndef HASHLIST_H
#define HASHLIST_H
#pragma pack(push,1)

#include "hash.h"

//---------------------------------------------------------
//	an item in the hash list
//---------------------------------------------------------
class CHashListItem
{
public:
	HASH	hashValue;
	void	*data;
};

//---------------------------------------------------------
//	static hash list implementation
//---------------------------------------------------------
class CStaticHashList
{
public:
	CStaticHashList() : m_nItems(0),m_pItems(0) { /*empty*/ }
	~CStaticHashList()	{ /*empty*/ }

	void		SetData( u32 nItems, CHashListItem *pItems);
	const void	*GetData() const		{	return m_pItems;						}
	u32			GetDataSize( ) const	{	return m_nItems*sizeof(CHashListItem);	}
	u32			GetNItems( ) const		{	return m_nItems;						}

	void		*FindByHash( HASH hashValue ) const;
	void		*FindByIndex( u32 index ) const;
	HASH		FindHashByIndex( u32 index ) const;
	bool		ItemExists( HASH hashValue, u32 *outIndex=0 ) const;

protected:
	// find the index where a hash value should go
	u32			FindIndexForHash( HASH hashValue );

protected:
	u32				m_nItems;
	CHashListItem	*m_pItems;
};

//---------------------------------------------------------
//	general case hash list implementation
//---------------------------------------------------------
class CHashList : public CStaticHashList
{
public:
	static void	SortItems( u32 numItems, CHashListItem *pItems );

public:
	CHashList() : CStaticHashList(), m_maxItems(0) { /*empty*/ }
	~CHashList();

	// inherited functionality
	//void	*FindByHash( HASH hashValue ) const;

	// clear the list
	void	Clear( bool freeMemory=false );

	// functions by hash
	bool	AddByHash( HASH hashValue, void *pData );
	bool	RemoveByHash( HASH hashValue );

	// functions by type
	template <class X>
	inline	bool	Add( X *pData )
	{
		return AddByHash(pData->MakeHash(),pData);
	}

	template <class X>
	inline	bool	Remove( const X *pData )
	{
		return RemoveByHash(pData->MakeHash());
	}

protected:

	u32				m_maxItems;
};

#pragma pack(pop)
#endif
